<?php

class request
{

// Объект, содержащий текущую (и единственную) копию объекта (Singleton)
static private $instance = null;

private $trackerId;     // Переменная, содержащая ID трекера
private $questionArray; // Переменная, содержащая массив с вопросами
private $answersArray;  // Переменная, содержащая массив с ответами
private $secretCode;    // Переменная, содержащая последний сгенерированный секретный код
private $trackerName;   // Переменная, содержащая название трекера

/**
 * Конструтор класса
 * 
 * @return void
 */
private function __construct() {
    // В дальнейшем тут будет код конструктора
}


/**
 * Функция возвращает текущий ID трекера
 * 
 * @return integer  Текущий ID трекера
 */
function getTrackerId() {
    return $this->trackerId;
}


/**
 * Функция записывает в переменную trackerId указанный ID трекера
 * 
 * @param  integer $id  ID трекера
 * @return void
 */
function setTrackerId($id) {
    $this->trackerId = (int)$id;
}


/**
 * Функция возвращает текущее название трекера
 * 
 * @return string  Текущее название трекера
 */
function getTrackerName() {
    return $this->trackerName;
}


/**
 * Функция записывает в переменную trackerName указанное название трекера
 * 
 * @param  string $name  Название трекера
 * @return void
 */
function setTrackerName($name) {
    $this->trackerName = $name;
}


/**
 * Функция возвращает список вопросов в виде массива
 * 
 * @return array  Список вопросов в виде массива
 */
function getQuestionsArray() {
    return $this->questionArray;
}


/**
 * Функция возвращает список вопросов в сериализированном виде
 * 
 * @return string  Список вопросов в сериализированном виде
 */
function getSerializedQuestionsArray() {
    return serialize($this->questionArray);
}


/**
 * Функция записывает в переменную array массив с вопросами
 * 
 * @param  array $array  Массив с вопросами
 * @return void
 */
function setQuestionsArray($array) {
    $this->questionArray = $array;
}


/**
 * Функция возвращает список ответов в виде массива
 * 
 * @return array  Список ответов в виде массива
 */
function getAnswersArray() {
    return $this->answersArray;
}


/**
 * Функция возвращает список ответов в сериализированном виде
 * 
 * @return string  Список ответов в сериализированном виде
 */
function getSerializedAnswersArray() {
    return serialize($this->answersArray);
}


/**
 * Функция записывает в переменную array массив с ответами
 * 
 * @param  array $array  Массив с ответами
 * @return void
 */
function setAnswersArray($array) {
    $this->answersArray = $array;
}


/**
 * Функция генерирует уникальный секретный код на основе функции mt_rand(). Функция присваевает
 * переменной secretCode этот код, а также возвращает это значение.
 *
 * @return string  Новый секретный код
 */
function generateSecretCode() {
    $secretCode = MD5(mt_rand());
    $this->secretCode = $secretCode;
    return $secretCode;
}


/**
 * Функция возвращает последний сгенерированный секретный код
 * 
 * @return string  Последний сгенерированный секретный код
 */
function getSecretCode() {
    return $this->secretCode;
}


/**
 * Функция добавляет новый запрос в базу даных
 * 
 * @return integer  ID последнего добавленного элемента
 */
function add() {
    // Блок проверки IP адреса
    try {
        mysql::getInstance()->select('requests', 'id', null, array('ip' => currentIp2long()));
        if (mysql::getInstance()->numRows() > MAX_REQ_BY_IP - 1) {
            throw new Exception('С вашего IP уже есть более двух нерассмотренных запросов. Подождите пока предыдущие запросы будут рассмотреннны и попобуйте позже.');
        }
    // Если проверка не прошла - выбрасываем исключение и возвращаем FALSE;
    } catch (Exception $e) {
        echo $e->getMessage();
        return false;
    }
    // Добавляем элемент в базу данных
    mysql::getInstance()->insert('requests', array('',
                                                  $this->getTrackerId(),                // ID
                                                  $this->getTrackerName(),              // Название
                                                  $this->generateSecretCode(),          // Код
                                                  INV_REQ_STANDART,                     // Статус
                                                  '',                                   // Причина
                                                  $this->getSerializedQuestionsArray(), // Вопросы
                                                  $this->getSerializedAnswersArray(),   // Ответы
                                                  currentIp2long(),                     // IP
                                                  time()));                             // Время
    return mysql::getInstance()->lastId(); // Возвращаем ID последнего добавленного элемента
}


/**
 * Функция принимает в качестве параметра ID запроса и возвращает массив с
 * информацией об этом запросе
 * 
 * @param  integer $requestSecret  ID запроса, по которому необходимо получить информацию
 * @param  mixed   $fields         Какие данные необходимо получать. По умолчанию функция
 *                                 получает все данные о запросе. Параметр может быть как
 *                                 массивом так и строкой.
 * @return array                   Массив с информацией о запросе
 */
function getDataBySecret($requestSecret, $fields = '*') {
    mysql::getInstance()->select('requests', '*', 1, array('secret' => $requestSecret));
    // Данные получаем только в случае, если в БД только один элемент с таким кодом
    if (mysql::getInstance()->numRows() == 1) {
        return mysql::getInstance()->fetch();
    }
}


/**
 * Функция возвращает объект, если он был создан. Если объект не создан - функция создаёт объект
 * и вызывает его (Singleton)
 *
 * @static
 * @return object  Текущая копия объекта
 */
static function getInstance() {
    if (self::$instance == null) {
        self::$instance = new self();
    }
    return self::$instance;
}

}